package org.java.base.channel;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 *  Java NIO通道类似于流，但有一些不同:
 *         1.可以对channel进行读写操作。stream通常是单向的(读或写)。
 *         2.channel可以异步读写。
 *         3.channel总是对缓冲区进行读操作或写操作。
 *                 FileChannel
 *                 DatagramChannel
 *                 SocketChannel
 *                 ServerSocketChannelExample
 *
 *
 */
public class ChannelExample {

    public static void main(String[] args) {
        ChannelExample  channelExample=new ChannelExample();
        channelExample.fileChannelExample();
    }

    /**
     * Buffer Capacity
     * Position 当将数据写入Buffer时，需要在某个位置写入数据。初始位置是0。当一个字节，长等已经写入缓冲区时，位置被提升到指向缓冲区中要插入数据的下一个单元格。位置最大可成为capacity- 1。
     * Limit   在写模式下，缓冲区的limit是可以写入缓冲区的数据量的限制。在写模式下，limit等于缓冲区的容量capacity。
     * Limit   当将Buffer切换到读模式时，limit意味着可以从数据中读取的数据数量的限制
     */
    public void fileChannelExample() {
        try {
            RandomAccessFile aFile = new RandomAccessFile("D:\\code\\leetcode-demo\\src\\main\\resources\\file\\RabbitMQ.txt", "rw");
            FileChannel inChannel = aFile.getChannel();

            //create buffer with capacity of 5 bytes
            ByteBuffer buf = ByteBuffer.allocate(5);

            int bytesRead = inChannel.read(buf); //read into buffer.
            while (bytesRead != -1) {

                buf.flip();  //将Buffer从写模式切换到读模式时

                while (buf.hasRemaining()) {
                    System.out.print((char) buf.get()); // read 1 byte at a time
                }

                //一旦你完成了从Buffer中读取数据，你必须让Buffer准备好再次写入。可以通过调用clear()或compact()来实现。
                buf.clear(); //make buffer ready for writing
                bytesRead = inChannel.read(buf);
            }
            aFile.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
